// Tags: Kruskal
#include <algorithm>
#include <cstdio>
#include <vector>

const int N = 1e5 + 5;
int n, m, k, cnt, tot, f[N];
struct Edge {
  int u, v, w;
} e[N];
std::vector<Edge> ans;

int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }

inline void init() {
  tot = 0, cnt = 0;
  for (int i = 1; i <= n; ++i) f[i] = i;
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("testdata.in", "r", stdin);
  freopen("testdata.out", "w", stdout);
#else
  freopen("P3623 [APIO2008]免费道路.in", "r", stdin);
  freopen("P3623 [APIO2008]免费道路.out", "w", stdout);
#endif
#endif

  scanf("%d%d%d", &n, &m, &k);
  for (int i = 1; i <= m; ++i) { scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w); }
  std::sort(e + 1, e + m + 1, [](const Edge &lhs, const Edge &rhs) -> bool {
    return lhs.w > rhs.w;
  });
  init();
  for (int i = 1; i <= m; ++i) {
    if (find(e[i].u) != find(e[i].v)) {
      f[find(e[i].u)] = find(e[i].v);
      ++tot;
      if (e[i].w == 0) ++cnt, e[i].w = -1;
    }
  }
  if (cnt > k || tot != n - 1) return puts("no solution"), 0;
  std::sort(e + 1, e + m + 1, [](const Edge &lhs, const Edge &rhs) -> bool {
    return lhs.w < rhs.w;
  });
  init();
  for (int i = 1; i <= m; ++i) {
    if (find(e[i].u) != find(e[i].v)) {
      if (e[i].w == 0 || e[i].w == -1) {
        if (cnt == k) continue;
        ++cnt;
      }
      f[find(e[i].u)] = find(e[i].v);
      ans.emplace_back(e[i]);
      ++tot;
    }
  }
  if (tot != n - 1 || cnt < k) return puts("no solution"), 0;
  for (auto &i : ans)
    printf("%d %d %d\n", i.u, i.v, (i.w == -1 || i.w == 0) ? 0 : 1);
  return 0;
}